/**************************************************************************************************
/// Copyright (c) 2006-2018, RT-Thread Development Team
/// All rights reserved.
///
/// \author: steven
///
/// \file: crc16.c
/// \brief: Functions for charge control.
///
///
///
/// \version: 1.0
/// \date: April. 04, 2022
**************************************************************************************************/
#include "board.h"
#include <rtthread.h>
#include "dmg_crc16.h"

/*CRC16 - XMODEM*/
/*the following crc table is generated by  CRC-CCITT = X16 + X12 + X5 + X0 */
const unsigned short crc16_table[256] =
{
    0X0000,  0X1021,  0X2042,  0X3063,
    0X4084,  0X50a5,  0X60c6,  0X70e7,
    0X8108,  0X9129,  0Xa14a,  0Xb16b,
    0Xc18c,  0Xd1ad,  0Xe1ce,  0Xf1ef,
    0X1231,  0X0210,  0X3273,  0X2252,
    0X52b5,  0X4294,  0X72f7,  0X62d6,
    0X9339,  0X8318,  0Xb37b,  0Xa35a,
    0Xd3bd,  0Xc39c,  0Xf3ff,  0Xe3de,
    0X2462,  0X3443,  0X0420,  0X1401,
    0X64e6,  0X74c7,  0X44a4,  0X5485,
    0Xa56a,  0Xb54b,  0X8528,  0X9509,
    0Xe5ee,  0Xf5cf,  0Xc5ac,  0Xd58d,
    0X3653,  0X2672,  0X1611,  0X0630,
    0X76d7,  0X66f6,  0X5695,  0X46b4,
    0Xb75b,  0Xa77a,  0X9719,  0X8738,
    0Xf7df,  0Xe7fe,  0Xd79d,  0Xc7bc,
    0X48c4,  0X58e5,  0X6886,  0X78a7,
    0X0840,  0X1861,  0X2802,  0X3823,
    0Xc9cc,  0Xd9ed,  0Xe98e,  0Xf9af,
    0X8948,  0X9969,  0Xa90a,  0Xb92b,
    0X5af5,  0X4ad4,  0X7ab7,  0X6a96,
    0X1a71,  0X0a50,  0X3a33,  0X2a12,
    0Xdbfd,  0Xcbdc,  0Xfbbf,  0Xeb9e,
    0X9b79,  0X8b58,  0Xbb3b,  0Xab1a,
    0X6ca6,  0X7c87,  0X4ce4,  0X5cc5,
    0X2c22,  0X3c03,  0X0c60,  0X1c41,
    0Xedae,  0Xfd8f,  0Xcdec,  0Xddcd,
    0Xad2a,  0Xbd0b,  0X8d68,  0X9d49,
    0X7e97,  0X6eb6,  0X5ed5,  0X4ef4,
    0X3e13,  0X2e32,  0X1e51,  0X0e70,
    0Xff9f,  0Xefbe,  0Xdfdd,  0Xcffc,
    0Xbf1b,  0Xaf3a,  0X9f59,  0X8f78,
    0X9188,  0X81a9,  0Xb1ca,  0Xa1eb,
    0Xd10c,  0Xc12d,  0Xf14e,  0Xe16f,
    0X1080,  0X00a1,  0X30c2,  0X20e3,
    0X5004,  0X4025,  0X7046,  0X6067,
    0X83b9,  0X9398,  0Xa3fb,  0Xb3da,
    0Xc33d,  0Xd31c,  0Xe37f,  0Xf35e,
    0X02b1,  0X1290,  0X22f3,  0X32d2,
    0X4235,  0X5214,  0X6277,  0X7256,
    0Xb5ea,  0Xa5cb,  0X95a8,  0X8589,
    0Xf56e,  0Xe54f,  0Xd52c,  0Xc50d,
    0X34e2,  0X24c3,  0X14a0,  0X0481,
    0X7466,  0X6447,  0X5424,  0X4405,
    0Xa7db,  0Xb7fa,  0X8799,  0X97b8,
    0Xe75f,  0Xf77e,  0Xc71d,  0Xd73c,
    0X26d3,  0X36f2,  0X0691,  0X16b0,
    0X6657,  0X7676,  0X4615,  0X5634,
    0Xd94c,  0Xc96d,  0Xf90e,  0Xe92f,
    0X99c8,  0X89e9,  0Xb98a,  0Xa9ab,
    0X5844,  0X4865,  0X7806,  0X6827,
    0X18c0,  0X08e1,  0X3882,  0X28a3,
    0Xcb7d,  0Xdb5c,  0Xeb3f,  0Xfb1e,
    0X8bf9,  0X9bd8,  0Xabbb,  0Xbb9a,
    0X4a75,  0X5a54,  0X6a37,  0X7a16,
    0X0af1,  0X1ad0,  0X2ab3,  0X3a92,
    0Xfd2e,  0Xed0f,  0Xdd6c,  0Xcd4d,
    0Xbdaa,  0Xad8b,  0X9de8,  0X8dc9,
    0X7c26,  0X6c07,  0X5c64,  0X4c45,
    0X3ca2,  0X2c83,  0X1ce0,  0X0cc1,
    0Xef1f,  0Xff3e,  0Xcf5d,  0Xdf7c,
    0Xaf9b,  0Xbfba,  0X8fd9,  0X9ff8,
    0X6e17,  0X7e36,  0X4e55,  0X5e74,
    0X2e93,  0X3eb2,  0X0ed1,  0X1ef0
};


/*
 * FUNCTION DEFINITIONS
 ****************************************************************************************
 */

/**
 ****************************************************************************************
 * @brief CRC16 calculation (X16 + X12 + X5 + X0)
 *
 * @param[in] p_data    Start address of data
 * @param[in] size      Data size
 *
 * @return Result of CRC16
 ****************************************************************************************
 */
unsigned short xmodem_crc16( unsigned char * p_data, unsigned long size )
{
    unsigned short crc16 = 0;

    for (uint32_t i=0; i < size; i++ )
        crc16 = ( crc16 << 8 ) ^ ( unsigned short )crc16_table[( crc16 >> 8 ) ^ *p_data++];

    return crc16;
}


/**crc16 -MODBUS*/
const char gabyCRCHi[] =
{
    0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,
    0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
    0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,
    0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
    0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x00,0xc1,
    0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,
    0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x00,0xc1,
    0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
    0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,
    0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,
    0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,
    0x81,0x40,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
    0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,
    0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,
    0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,
    0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
    0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,
    0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
    0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,
    0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
    0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x01,0xc0,
    0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,
    0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,
    0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
    0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,
    0x80,0x41,0x00,0xc1,0x81,0x40
};
const char gabyCRCLo[] =
{
    0x00,0xc0,0xc1,0x01,0xc3,0x03,0x02,0xc2,0xc6,0x06,
    0x07,0xc7,0x05,0xc5,0xc4,0x04,0xcc,0x0c,0x0d,0xcd,
    0x0f,0xcf,0xce,0x0e,0x0a,0xca,0xcb,0x0b,0xc9,0x09,
    0x08,0xc8,0xd8,0x18,0x19,0xd9,0x1b,0xdb,0xda,0x1a,
    0x1e,0xde,0xdf,0x1f,0xdd,0x1d,0x1c,0xdc,0x14,0xd4,
    0xd5,0x15,0xd7,0x17,0x16,0xd6,0xd2,0x12,0x13,0xd3,
    0x11,0xd1,0xd0,0x10,0xf0,0x30,0x31,0xf1,0x33,0xf3,
    0xf2,0x32,0x36,0xf6,0xf7,0x37,0xf5,0x35,0x34,0xf4,
    0x3c,0xfc,0xfd,0x3d,0xff,0x3f,0x3e,0xfe,0xfa,0x3a,
    0x3b,0xfb,0x39,0xf9,0xf8,0x38,0x28,0xe8,0xe9,0x29,
    0xeb,0x2b,0x2a,0xea,0xee,0x2e,0x2f,0xef,0x2d,0xed,
    0xec,0x2c,0xe4,0x24,0x25,0xe5,0x27,0xe7,0xe6,0x26,
    0x22,0xe2,0xe3,0x23,0xe1,0x21,0x20,0xe0,0xa0,0x60,
    0x61,0xa1,0x63,0xa3,0xa2,0x62,0x66,0xa6,0xa7,0x67,
    0xa5,0x65,0x64,0xa4,0x6c,0xac,0xad,0x6d,0xaf,0x6f,
    0x6e,0xae,0xaa,0x6a,0x6b,0xab,0x69,0xa9,0xa8,0x68,
    0x78,0xb8,0xb9,0x79,0xbb,0x7b,0x7a,0xba,0xbe,0x7e,
    0x7f,0xbf,0x7d,0xbd,0xbc,0x7c,0xb4,0x74,0x75,0xb5,
    0x77,0xb7,0xb6,0x76,0x72,0xb2,0xb3,0x73,0xb1,0x71,
    0x70,0xb0,0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,
    0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9c,0x5c,
    0x5d,0x9d,0x5f,0x9f,0x9e,0x5e,0x5a,0x9a,0x9b,0x5b,
    0x99,0x59,0x58,0x98,0x88,0x48,0x49,0x89,0x4b,0x8b,
    0x8a,0x4a,0x4e,0x8e,0x8f,0x4f,0x8d,0x4d,0x4c,0x8c,
    0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,
    0x43,0x83,0x41,0x81,0x80,0x40
};

unsigned short ModbusCRC(char * pData, unsigned long len)
{
    char byCRCHi = 0xff;
    char byCRCLo = 0xff;
    char byIdx;
    unsigned short crc;
    while(len--) {
        byIdx = byCRCHi ^* pData++;
        byCRCHi = byCRCLo ^ gabyCRCHi[byIdx];
        byCRCLo = gabyCRCLo[byIdx];
    }
    crc = byCRCHi;
    crc <<= 8;
    crc += byCRCLo;
    return crc;
}


//unsigned short crc_recv;
//void crcModbusTest(void)
//{
//  char str[]={0x68,0x0c,0x00,0x00,0x00,0x02,0x55,0x03,0x14,0x12,0x78,0x23,0x05,0x00,0xda,0x4c};
//  char length = sizeof(str);
//  crc_recv = ModbusCRC(&str[2],length -4);
//}
//MSH_CMD_EXPORT(crcModbusTest , mobuscrctest);



//endif
